﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using WenSkin.Controls;

namespace WenSkin.Forms
{
    public partial class WenForm : Form
    {
        public WenForm()
        {
            InitializeComponent();
            RefreshPadding();
            SystemButtonAdd();

            base.SetStyle(
                ControlStyles.UserPaint |
                ControlStyles.DoubleBuffer |
                ControlStyles.OptimizedDoubleBuffer |
                ControlStyles.AllPaintingInWmPaint |
                ControlStyles.ResizeRedraw |
                ControlStyles.SupportsTransparentBackColor, true);
            base.UpdateStyles();
            this.MaximizedBounds = Screen.PrimaryScreen.WorkingArea;
            this.BackColor = Color.FromArgb(37, 37, 38);
            this.ForeColor = Color.White;
        }

        #region 私有属性
        private int buttonPointX = 0;
        private int frameWidth = 3;
        private int titleHeight = 30;
        private Color frameColor = Color.FromArgb(45, 45, 48);
        private Color backColor = Color.FromArgb(30, 30, 30);
        private Color foreColor = Color.FromArgb(255, 255, 255);
        private bool configButtonBox;
        private bool skinButtonBox;
        #endregion

        #region 公有属性
        [DefaultValue(4), Category("Wen"), Description("边框宽度"), RefreshProperties(RefreshProperties.All)]
        public int FrameWidth
        {
            get => frameWidth;
            set
            {
                frameWidth = value;
                RefreshPadding();
            }
        }

        [DefaultValue(30), Category("Wen"), Description("标题高度"), RefreshProperties(RefreshProperties.All)]
        public int TitleHeight
        {
            get => titleHeight;
            set
            {
                titleHeight = value;
                RefreshPadding();
            }
        }


        [DefaultValue(typeof(Color), "45, 45, 48"), Category("WenColor"), Description("边框颜色")]
        public Color FrameColor
        {
            get => frameColor;
            set
            {
                frameColor = value;
                FrameColorChanged?.Invoke(this, null);
                this.Invalidate();
            }
        }
        [DefaultValue(typeof(Color), "255, 255, 255"), Category("WenColor"), Description("前景色")]
        public override Color ForeColor
        {
            get => foreColor;
            set
            {
                foreColor = value;
                base.ForeColor = value;
                this.Invalidate();
            }
        }

        [DefaultValue(typeof(Color), "37, 37, 38"), Category("WenColor"), Description("背景色")]
        public override Color BackColor
        {
            get => this.backColor;
            set
            {
                //若为系统颜色改为酷黑色
                if (value == System.Drawing.SystemColors.Control)
                {
                    value = Color.FromArgb(37, 37, 38);
                }
                base.BackColor = value;
                this.backColor = value;
                this.Invalidate();
            }
        }

        [DefaultValue(false), Category("Wen"), Description("是否显示设置按钮")]
        public bool ConfigButtonBox
        {
            get => configButtonBox;
            set
            {
                configButtonBox = value;
                SystemButtonAdd();
            }
        }

        [DefaultValue(false), Category("Wen"), Description("是否显示皮肤按钮")]
        public bool SkinButtonBox
        {
            get => skinButtonBox;
            set
            {
                skinButtonBox = value;
                SystemButtonAdd();
            }
        }
        [DefaultValue(true), Category("Wen"), Description("窗体是否可拉伸大小")]
        public bool Stretching { get; set; } = true;
        #endregion

        #region 委托

        [Category("Wen"), Description("边框颜色改变事件")]
        public event EventHandler FrameColorChanged;

        [Category("Wen"), Description("设置按钮点击事件")]
        public event EventHandler ConfigButtonClick;

        [Category("Wen"), Description("皮肤按钮点击事件")]
        public event EventHandler SkinButtonClick;
        #endregion

        #region 重写属性

        public override string Text
        {
            get => base.Text;
            set
            {
                base.Text = value;
                this.Invalidate();
            }
        }

        #endregion

        #region 刷新控件边框标题区域
        protected virtual void RefreshPadding()
        {
            this.Padding = new Padding() { Top = TitleHeight, Left = FrameWidth, Bottom = FrameWidth, Right = FrameWidth };
            this.Invalidate();
        }
        #endregion

        #region 重绘
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;
            WenSkin.Controls.ControlHelper.SetGDIHigh(g);
            DrawRecFrame(g);
            DrawTitle(g);
        }
        #endregion

        #region 重绘边框
        private void DrawRecFrame(Graphics g)
        {
            //绘制4个框背景
            Brush b = new SolidBrush(FrameColor);
            //左边
            g.FillRectangle(b, 0, 0, FrameWidth, this.Height);
            //右边
            g.FillRectangle(b, this.Width - FrameWidth, 0, FrameWidth, this.Height);
            //底部
            g.FillRectangle(b, 0, this.Height - FrameWidth, this.Width, FrameWidth);

            //绘制标题行背景
            g.FillRectangle(b, 0, 0, this.Width, TitleHeight);
        }
        #endregion

        #region 重绘标题行
        private void DrawTitle(Graphics g)
        {
            //标题行绘制
            if (this.Icon != null)
            {
                g.DrawImage(this.Icon.ToBitmap(), new Rectangle(7, 7, 16, 16));
            }
            Rectangle recText = new Rectangle(30, 0, this.Width - buttonPointX - 30, 30);
            g.DrawString(this.Text, Font, new SolidBrush(this.ForeColor), recText, WenSkin.Controls.ControlHelper.StringConters);
        }
        #endregion

        #region 添加系统按钮

        public new bool MaximizeBox
        {
            get => base.MaximizeBox;
            set
            {
                base.MaximizeBox = value;
                SystemButtonAdd();
            }
        }
        public new bool MinimizeBox
        {
            get => base.MinimizeBox;
            set
            {
                base.MinimizeBox = value;
                SystemButtonAdd();
            }
        }

        private void SystemButtonAdd()
        {
            buttonPointX = 0;
            CloseButtonAdd();
            MaxButtonAdd();
            MinButtonAdd();
            ConfigButtonAdd();
            SkinButtonAdd();
        }

        #region 添加关闭按钮
        private void CloseButtonAdd()
        {
            if (this.Controls["SystemButtonClose"] is WenControl close)
            {
                this.Controls.Remove(close);
            }

            buttonPointX += 46;
            int x = buttonPointX;

            WenControl wenControl = new WenControl()
            {
                BackColor = Color.Transparent,
                Width = 46,
                Height = 30,
                Location = new Point(this.Width - x, 0),
                Name = "SystemButtonClose"
            };
            wenControl.MouseEnter += (s, e) =>
            {
                wenControl.BackColor = Color.FromArgb(63, 63, 65);
            };
            wenControl.MouseLeave += (s, e) =>
            {
                wenControl.BackColor = Color.Transparent;
            };
            wenControl.Paint += (s, e) =>
            {
                Graphics g = e.Graphics;
                g.SetGDIHigh();

                using Pen p = new Pen(Color.White, 1);

                g.DrawLine(p, 18, 11, 18 + 8, 11 + 8);
                g.DrawLine(p, 18, 11 + 8, 18 + 8, 11);
            };
            wenControl.Click += (s, e) =>
            {
                this.Close();
            };

            this.SizeChanged += (s, e) =>
            {
                wenControl.Location = new Point(this.Width - x, 0);
            };
            this.Controls.Add(wenControl);
        }
        #endregion

        #region 添加最大化按钮
        private void MaxButtonAdd()
        {
            if (this.Controls["SystemButtonMax"] is WenControl max)
            {
                this.Controls.Remove(max);
            }
            if (!MaximizeBox)
                return;

            buttonPointX += 46;
            int x = buttonPointX;

            WenControl wenControl = new WenControl()
            {
                BackColor = Color.Transparent,
                Width = 46,
                Height = 30,
                Location = new Point(this.Width - x, 0),
                Name = "SystemButtonMax"
            };
            wenControl.MouseEnter += (s, e) =>
            {
                wenControl.BackColor = Color.FromArgb(63, 63, 65);
            };
            wenControl.MouseLeave += (s, e) =>
            {
                wenControl.BackColor = Color.Transparent;
            };
            wenControl.Paint += (s, e) =>
            {
                Graphics g = e.Graphics;
                g.SetGDIHigh();

                using Pen p = new Pen(Color.White, 1);

                if (this.WindowState == FormWindowState.Maximized)
                {
                    g.DrawRectangle(p, 18, 11 + 2, 6, 6);
                    g.DrawRectangle(p, 18 + 2, 11, 6, 6);
                }
                else
                {
                    g.DrawRectangle(p, 18, 11, 8, 8);
                }
            };

            wenControl.Click += (s, e) =>
            {
                if (WindowState == FormWindowState.Maximized)
                {
                    this.WindowState = FormWindowState.Normal;
                }
                else
                {
                    this.WindowState = FormWindowState.Maximized;
                }
            };

            this.SizeChanged += (s, e) =>
            {
                wenControl.Location = new Point(this.Width - x, 0);
            };
            this.Controls.Add(wenControl);
        }
        #endregion

        #region 最小化按钮
        private void MinButtonAdd()
        {
            if (this.Controls["SystemButtonMin"] is WenControl min)
            {
                this.Controls.Remove(min);
            }

            if (!MinimizeBox)
                return;

            buttonPointX += 46;
            int x = buttonPointX;

            WenControl wenControl = new WenControl()
            {
                BackColor = Color.Transparent,
                Width = 46,
                Height = 30,
                Location = new Point(this.Width - x, 0),
                Name = "SystemButtonMin"
            };
            wenControl.MouseEnter += (s, e) =>
            {
                wenControl.BackColor = Color.FromArgb(63, 63, 65);
            };
            wenControl.MouseLeave += (s, e) =>
            {
                wenControl.BackColor = Color.Transparent;
            };
            wenControl.Paint += (s, e) =>
            {
                Graphics g = e.Graphics;
                g.SetGDIHigh();

                using Pen p = new Pen(Color.White, 1);

                g.DrawLine(p, 18, 15, 18 + 8, 15);
            };
            wenControl.Click += (s, e) =>
            {
                this.WindowState = FormWindowState.Minimized;
            };

            this.SizeChanged += (s, e) =>
            {
                wenControl.Location = new Point(this.Width - x, 0);
            };
            this.Controls.Add(wenControl);
        }
        #endregion

        #region 设置按钮
        private void ConfigButtonAdd()
        {
            if (this.Controls["SystemButtonConfig"] is WenControl c)
            {
                this.Controls.Remove(c);
            }

            if (!ConfigButtonBox)
                return;

            buttonPointX += 46;
            int x = buttonPointX;

            WenControl wenControl = new WenControl()
            {
                BackColor = Color.Transparent,
                Width = 46,
                Height = 30,
                Location = new Point(this.Width - x, 0),
                Name = "SystemButtonConfig"
            };
            wenControl.MouseEnter += (s, e) =>
            {
                wenControl.BackColor = Color.FromArgb(63, 63, 65);
            };
            wenControl.MouseLeave += (s, e) =>
            {
                wenControl.BackColor = Color.Transparent;
            };
            wenControl.Paint += (s, e) =>
            {
                Graphics g = e.Graphics;
                g.SetGDIHigh();

                g.DrawImage(Properties.Resources.setbutton, new Rectangle(13, 5, 20, 20));
            };
            wenControl.Click += (s, e) =>
            {
                ConfigButtonClick?.Invoke(this, e);
            };

            this.SizeChanged += (s, e) =>
            {
                wenControl.Location = new Point(this.Width - x, 0);
            };
            this.Controls.Add(wenControl);
        }
        #endregion

        #region 皮肤按钮
        private void SkinButtonAdd()
        {
            if (this.Controls["SystemButtonSkin"] is WenControl c)
            {
                this.Controls.Remove(c);
            }

            if (!SkinButtonBox)
                return;

            buttonPointX += 46;
            int x = buttonPointX;

            WenControl wenControl = new WenControl()
            {
                BackColor = Color.Transparent,
                Width = 46,
                Height = 30,
                Location = new Point(this.Width - x, 0),
                Name = "SystemButtonSkin"
            };
            wenControl.MouseEnter += (s, e) =>
            {
                wenControl.BackColor = Color.FromArgb(63, 63, 65);
            };
            wenControl.MouseLeave += (s, e) =>
            {
                wenControl.BackColor = Color.Transparent;
            };
            wenControl.Paint += (s, e) =>
            {
                Graphics g = e.Graphics;
                g.SetGDIHigh();

                g.DrawImage(Properties.Resources.skin, new Rectangle(13, 5, 20, 20));
            };
            wenControl.Click += (s, e) =>
            {
                SkinButtonClick?.Invoke(this, e);
            };

            this.SizeChanged += (s, e) =>
            {
                wenControl.Location = new Point(this.Width - x, 0);
            };
            this.Controls.Add(wenControl);
        }
        #endregion

        #endregion

        #region 鼠标双击事件
        protected override void OnDoubleClick(EventArgs e)
        {
            base.OnDoubleClick(e);
            if (!MaximizeBox)
                return;
            if (WindowState == FormWindowState.Maximized)
            {
                this.WindowState = FormWindowState.Normal;
            }
            else
            {
                this.WindowState = FormWindowState.Maximized;
            }
        }
        #endregion

        #region 窗体拉动大小及拖动窗口

        const int Guying_HTLEFT = 10;
        const int Guying_HTRIGHT = 11;
        const int Guying_HTTOP = 12;
        const int Guying_HTTOPLEFT = 13;
        const int Guying_HTTOPRIGHT = 14;
        const int Guying_HTBOTTOM = 15;
        const int Guying_HTBOTTOMLEFT = 0x10;
        const int Guying_HTBOTTOMRIGHT = 17;
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case 0x0084:
                    base.WndProc(ref m);
                    if (!Stretching)
                        return;
                    Point vPoint = new Point((int)m.LParam & 0xFFFF,
                    (int)m.LParam >> 16 & 0xFFFF);
                    vPoint = PointToClient(vPoint);
                    if (vPoint.X <= 5)
                        if (vPoint.Y <= 5)
                            m.Result = (IntPtr)Guying_HTTOPLEFT;
                        else if (vPoint.Y >= ClientSize.Height - 5)
                            m.Result = (IntPtr)Guying_HTBOTTOMLEFT;
                        else m.Result = (IntPtr)Guying_HTLEFT;
                    else if (vPoint.X >= ClientSize.Width - 5)
                        if (vPoint.Y <= 5)
                            m.Result = (IntPtr)Guying_HTTOPRIGHT;
                        else if (vPoint.Y >= ClientSize.Height - 5)
                            m.Result = (IntPtr)Guying_HTBOTTOMRIGHT;
                        else m.Result = (IntPtr)Guying_HTRIGHT;
                    else if (vPoint.Y <= 5)
                        m.Result = (IntPtr)Guying_HTTOP;
                    else if (vPoint.Y >= ClientSize.Height - 5)
                        m.Result = (IntPtr)Guying_HTBOTTOM;         
                    break;
                case 0x0201: //鼠标左键按下的消息
                    m.Msg = 0x00A1; //更改消息为非客户区按下鼠标
                    m.LParam = IntPtr.Zero; //默认值
                    m.WParam = new IntPtr(2);//鼠标放在标题栏内
                    base.WndProc(ref m);
                    break;
                default:
                    base.WndProc(ref m); 
                    break;
            }
        }
        #endregion

        #region 消息提示框
        /// <summary>
        /// 消息
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public bool MsgBoxInformation(string text)
        {
            //var m = MessageBox.Show(text, "提醒", MessageBoxButtons.OK, MessageBoxIcon.Information);
            var m = new MsgBox(text, MsgBox.MsgBoxIcon.Info).ShowDialog();
            if (m == DialogResult.OK)
                return true;
            else
                return false;
        }
        /// <summary>
        /// 提醒
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public bool MsgBoxAsterisk(string text)
        {
            //var m = MessageBox.Show(text, "提醒", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk);
            var m = new MsgBox(text, MsgBox.MsgBoxIcon.Asterisk).ShowDialog();
            if (m == DialogResult.OK)
                return true;
            else
                return false;
        }
        /// <summary>
        /// 警告
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public bool MsgBoxWarning(string text)
        {
            //var m = MessageBox.Show(text, "警告", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
            var m = new MsgBox(text, MsgBox.MsgBoxIcon.Warning).ShowDialog();
            if (m == DialogResult.OK)
                return true;
            else
                return false;
        }
        /// <summary>
        /// 错误
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public bool MsgBoxError(string text)
        {
            //var m = MessageBox.Show(text, "错误", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
            var m = new MsgBox(text, MsgBox.MsgBoxIcon.Error).ShowDialog();
            if (m == DialogResult.OK)
                return true;
            else
                return false;
        }
        #endregion

    }
}
